package cn.jinjimi.app.main.fragment;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebBackForwardList;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.tencent.bugly.crashreport.CrashReport;

import cn.jinjimi.base.util.LogUtil;
import cn.jinjimi.base.util.Scheme;
import cn.jinjimi.base.util.StringUtils;
import cn.jinjimi.base.util.ToastUtils;
import cn.jinjimi.base.util.URLUtil;
import cn.jinjimi.framework.helper.annotation.EventTrace;
import cn.jinjimi.framework.helper.annotation.EventTraceParam;
import cn.jinjimi.app.AccountManager;
import cn.jinjimi.app.R;
import cn.jinjimi.app.ShareProxy;
import cn.jinjimi.app.webview.WebViewJavascriptBridge;
import cn.jinjimi.app.webview.WebViewHelper;
import cn.jinjimi.app.webview.utils.WebUtils;
import cn.jinjimi.app.bean.EventDataField;
import cn.jinjimi.app.bean.EventID;
import cn.jinjimi.app.bean.BundleKey;
import cn.jinjimi.app.bean.QuesCode;
import cn.jinjimi.app.controller.event.CallShareDialogEvent;
import cn.jinjimi.app.controller.event.CollecCancleEvent;
import cn.jinjimi.app.controller.event.CollectEvent;
import cn.jinjimi.app.controller.event.DataEvent;
import cn.jinjimi.app.controller.event.LocalEvent.ReaderShareEvent;
import cn.jinjimi.app.controller.event.LoginSuccessEvent;
import cn.jinjimi.app.controller.event.OpenCustomHomeEvent;
import cn.jinjimi.domain.ServiceManager;
import cn.jinjimi.domain.store.ReaderStore;
import cn.jinjimi.app.entity.Account;
import cn.jinjimi.app.entity.Article;
import cn.jinjimi.app.entity.ArticleCollect;
import cn.jinjimi.app.entity.ArticleMeta;
import cn.jinjimi.app.entity.WebRedirectEvent;
import cn.jinjimi.framework.router.Router;
import cn.jinjimi.app.bean.RouterConstants;
import cn.jinjimi.framework.router.RouterHelper;
import cn.jinjimi.app.main.activity.LoginActivity;
import cn.jinjimi.app.main.dialog.ShareDialog;
import cn.jinjimi.app.main.dialog.ShareWithoutLoginDialog;
import cn.jinjimi.app.main.extend.BaseNetControlFragment;
import cn.jinjimi.app.main.widget.MyWebView;
import cn.jinjimi.app.util.PhotoUtils;
import cn.jinjimi.app.util.ToastUtil;
import cn.jinjimi.app.util.UploadPhotosUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

import bolts.Continuation;
import bolts.Task;

import static cn.jinjimi.app.R.id.tv_share;

/**
 * Created by Roy
 * Date: 15/10/21
 */
public class ReaderDetailFragment extends BaseNetControlFragment {

    private final static String loginedStr;
    private final static String anonyStr;
    private WebViewJavascriptBridge handler;
    private String mLastUrl;

    /* Data and State */
    private Map<String, String> mHttpHeaders;

    static {
        String base = "channel_id=1&anonymous=%d";
        loginedStr = String.format(base, 0);
        anonyStr = String.format(base, 1) + "&anonymous_id=" + AccountManager.getInstance().getAccount().uuid;
    }

    private Map<String, ArticleMeta> mArticleDataCache = new HashMap<>();

    private MyWebView webView;

    private String linkUrl;
    private String articleId;
    private ArticleMeta articleMeta;

    private String fSource;

    private ImageView imageCollect;
    private RelativeLayout mShareBarView;

    private OnUrlChangeListener mUrlChangeListener;

    private boolean hasClearHistory = false;
    private boolean hasNetError = false;
    private boolean canShareColl = false;
    private String notifyUrl;

    /* 监听URL状态变化的接口协议 */
    private interface OnUrlChangeListener {
        void onChange(String currentUrl, String forwardUrl, String backUrl);
    }

    @Override
    protected int getBizLayoutResourceId() {
        return R.layout.fragment_article_detail;
    }

    @Override
    protected void initialBiz() {
        articleMeta = new ArticleMeta();
        initView();
        initListener();

        CrashReport.setJavascriptMonitor(webView, false);
    }

    private void initView() {
        webView = (MyWebView) findView().findViewById(R.id.webView);

        mShareBarView = (RelativeLayout) findView().findViewById(R.id.ll_buttomBar);
        imageCollect = (ImageView) findView().findViewById(R.id.iv_collect);

        //获取数据
        Intent intent = getActivity().getIntent();
        String id = intent.getStringExtra("id");
        articleId = intent.getStringExtra(BundleKey.ARTICLE_ID);
        notifyUrl = intent.getStringExtra(BundleKey.APP_NOTIFY_URL);
        if (StringUtils.isNotEmpty(id))//是否是路由跳转过来的
            articleId = id;

        fSource = intent.getStringExtra(BundleKey.SOURCE);
        if (intent.hasExtra(BundleKey.ARTICLE_LINK)) {
            linkUrl = intent.getStringExtra(BundleKey.ARTICLE_LINK);
            buildLoadUrl();
        }

        initWebView();
    }

    protected void initListener() {
        findView().findViewById(tv_share).setOnClickListener(this);
        imageCollect.setOnClickListener(this);
    }

    /* 初始化WebView */
    private void initWebView() {
        WebChromeClient webChromeClient = new WebChromeClient() {
            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                renderWithUrlFromFirst(view.getOriginalUrl());
            }
        };


        WebViewHelper.setUpWebView(getActivity(), webView);

        handler = new WebViewJavascriptBridge(webView);

        webView.setWebChromeClient(webChromeClient);
        webView.setWebViewClient(new ReaderWebViewClient(getActivity()));


        //监听URL状态变化
        mUrlChangeListener = new OnUrlChangeListener() {
            @Override
            public void onChange(String currentUrl, String forwardUrl, String backUrl) {
                LogUtil.d("urlMsg", "current=" + currentUrl);
                LogUtil.d("urlMsg", "forward=" + forwardUrl);
                LogUtil.d("urlMsg", "back=" + backUrl);

                renderWithURL(currentUrl);
            }
        };

    }

    private class ReaderWebViewClient extends WebViewHelper.WebViewClient {
        public ReaderWebViewClient(Activity activity) {
            super(activity);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            super.shouldOverrideUrlLoading(view, url);
            if (StringUtils.isEmpty(url))
                return true;

            if (getActivity() == null || getActivity().isFinishing())
                return true;

            if (RouterHelper.isNativeUrl(url)) { // 使用本地路由打开原生界面
                Router.create(view.getContext(), url).open();
                return true;
            } else if (url.startsWith(Scheme.TEL)) {
                Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
                startActivity(intent);
                return true;
            } else if (url.startsWith("http:") || url.startsWith("https:")) {
                ArticleMeta articleMeta = WebUtils.getArticleDTOFromUrl(url);
                if (StringUtils.isNotEmpty(articleMeta.getId())) {
                    articleId = articleMeta.getId();
                    linkUrl = url;
                    netLoadingData();
                } else {
                    //view.loadUrl(url, null);
                    Router.create(view.getContext(), url).open();
                }
                return true;
            }
            return false;
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            netLoadFaiEmpty();
            hasNetError = true;
            canShareColl = false;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (!hasNetError) {
                netLoadSucc();
                canShareColl = true;
            }
            if (hasClearHistory) {
                view.clearHistory();
                hasClearHistory = false;
            }
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            mLastUrl = url;
        }
    }

    @Override
    protected void loadData() {
        if (StringUtils.isNotEmpty(linkUrl)) {
            loadUrl(linkUrl, getHttpHeaders());
        }
        hasNetError = false;
        queryArticle();
    }

    /* 在加载网页之后从网络上查询文章详情 */
    private void queryArticle() {
        Task.callInBackground(new Callable<ArticleMeta>() {
            @Override
            public ArticleMeta call() throws Exception {
                return ServiceManager.getService(ReaderStore.class).getArticleMetaData(articleId);
            }
        }).continueWith(new Continuation<ArticleMeta, Void>() {
            @Override
            public Void then(Task<ArticleMeta> task) throws Exception {
                if (checkActivityExit())
                    return null;
                ArticleMeta artcle = task.getResult();
                if (!task.isFaulted() && artcle != null) {
                    articleMeta = artcle;
                    render(articleMeta);
                } else if (StringUtils.isEmpty(linkUrl)) {
                    netLoadFaiEmpty();
                }
                return null;
            }
        }, Task.UI_THREAD_EXECUTOR);
    }

    /* 首次打开根据Url判断是否显示分享状态栏 */
    private void renderWithUrlFromFirst(String currentUrl) {
        if (StringUtils.isNotEmpty(currentUrl)
                && (currentUrl.startsWith("https:")
                || currentUrl.startsWith("http:"))) {

            ArticleMeta ado = WebUtils.getArticleDTOFromUrl(currentUrl);
            if (StringUtils.isNotEmpty(ado.getId())) {
                //如果是文章页面显示分享状态栏
                showShareBar(true);
            } else {
                showShareBar(false);
            }
        }
    }

    private void renderWithURL(String currentUrl) {
        if (currentUrl != null
                && (currentUrl.startsWith("https:")
                || currentUrl.startsWith("http:"))) {

            ArticleMeta ado = WebUtils.getArticleDTOFromUrl(currentUrl);
            if (!TextUtils.isEmpty(ado.getId())) {
                //如果是文章页面显示分享状态栏
                showShareBar(true);

                ArticleMeta cached = cache(ado.getId());
                if (cached != null) {
                    articleMeta = cached;
                    render(cached);
                } else {
                    articleId = ado.getId();
                    queryArticle();
                }

            } else {
                showShareBar(false);
            }
        }
    }

    private void render(ArticleMeta meta) {
        if (meta == null) return;

        cache(meta);

        if (StringUtils.isEmpty(linkUrl)) loadWebPage(meta);

        showShareBar(true);
        changeCollectBg();
    }

    /* webView缓存机制 */
    private void cache(ArticleMeta meta) {
        if (mArticleDataCache != null) {
            if (meta != null) {
                mArticleDataCache.put(meta.getId(), meta);
            }
        }
    }

    private void updateCache(String id, ArticleCollect articleCollect) {
        if (mArticleDataCache != null) {
            ArticleMeta articleMeta = mArticleDataCache.get(id);
            articleMeta.setArticle_collect(articleCollect);
        }
    }

    private ArticleMeta cache(String id) {
        if (mArticleDataCache != null) {
            return mArticleDataCache.get(id);
        }
        return null;
    }

    /**
     * webview 加载数据
     *
     * @param articleData
     */
    private void loadWebPage(ArticleMeta articleData) {
        if (StringUtils.isNotEmpty(articleData.getLink())) {
            linkUrl = articleData.getLink();
            buildLoadUrl();
        }

        loadUrl(linkUrl, getHttpHeaders());
    }

    private Map<String, String> getHttpHeaders() {
        if (mHttpHeaders == null) {
            mHttpHeaders = new HashMap<>();
        }
        return mHttpHeaders;
    }

    /* 首次进入或者query回来的articleUrl进行拼接处理 */
    private void buildLoadUrl() {
        linkUrl += linkUrl.contains("?") ? "&" : "?";

        //判断是否匿名用户打开网页
        if (AccountManager.getInstance().isLogin()) {
            linkUrl += loginedStr + "&sso_id=" + AccountManager.getInstance().getAccount().ssoid;
        } else {
            linkUrl += anonyStr;
        }

        /* 来源统计 1.8.3添加 */
        if (StringUtils.isNotEmpty(fSource)) {
            linkUrl += "&f_source=" + fSource;
        }
    }

    private void loadUrl(String url, Map<String, String> httpHeaders) {
        if (WebUtils.isDoubleClick()) {
            return;
        }

        boolean isXrkDomain = WebUtils.isDomain(url);
        if (isXrkDomain) {
            Account account = AccountManager.getInstance().getAccount();

            Map<String, String> bi = new HashMap<>();
            bi.put("token", account.token);

            if (webViewIsPermit())
                webView.loadUrl(URLUtil.appendParam(url, bi), httpHeaders);
        } else {
            if (webViewIsPermit())
                webView.loadUrl(url);
        }
    }

    /**
     * 控制是否显示分享状态栏
     *
     * @param show
     */
    private void showShareBar(boolean show) {
        if (mShareBarView != null) {
            mShareBarView.setVisibility(show ? View.VISIBLE : View.GONE);
        }
    }

    /* 修改收藏图标背景 */
    private void changeCollectBg() {
        if (articleMeta.isCollect()) {
            imageCollect.setImageResource(R.drawable.nav_icon_favok);
        } else {
            imageCollect.setImageResource(R.drawable.nav_icon_fav);
        }
    }

    @Override
    public void onClick(View v) {
        super.onClick(v);
        if (!canShareColl) return;
        switch (v.getId()) {
            case tv_share:
                doShare();
                break;
            case R.id.iv_collect:
                doCollect();
                break;
        }
    }

    private void doCollect() {
        if (AccountManager.getInstance().isLogin()) {
            collectArticle();
        } else {
            Intent intent = new Intent(getActivity(), LoginActivity.class);
            startActivityForResult(intent, QuesCode.QuestCollectArticle);
        }
    }

    /* 处理收藏文章 */
    private void collectArticle() {
        if (articleMeta.isCollect()) {
            cancleCollect();
        } else if (articleMeta != null && !TextUtils.isEmpty(articleMeta.getId())){
            Task.callInBackground(new Callable<Article>() {
                @Override
                public Article call() throws Exception {
                    return ServiceManager.getService(ReaderStore.class).collect(
                            AccountManager.getInstance().getAccount().ssoid, articleMeta.getId()
                    );
                }
            });
        }
    }

    /* 取消收藏文章 */
    private void cancleCollect() {
        if (null != articleMeta.getArticle_collect()) {
            final String id = articleMeta.getArticle_collect().getId();
            Task.callInBackground(new Callable<Boolean>() {
                @Override
                public Boolean call() throws Exception {
                    return ServiceManager.getService(ReaderStore.class).unCollect(id);
                }
            });
        }
    }

    private void doShare() {
        if (AccountManager.getInstance().isLogin()) {
            shareArticle();
        } else {
            ShareWithoutLoginDialog dialog = new ShareWithoutLoginDialog(getActivity());
            dialog.show();
        }
        if (!webViewIsPermit())
            return;
        doShareWithAnalyse(webView.getUrl(), getActivity().getIntent().getStringExtra(BundleKey.SOURCE));
    }

    @EventTrace(EventID.APP_SHARE_CLICK)
    private void doShareWithAnalyse(@EventTraceParam(EventDataField.ParamFrom) String url, @EventTraceParam(EventDataField.ParamSource) String fSource) {
    }

    /* 分享文章 */
    private void shareArticle() {
        if (articleMeta == null
                || StringUtils.isEmpty(articleMeta.getId())) {
            ToastUtils.toastMessage(getActivity(), R.string.loading_data_for_share);
            return;
        }

        if (!webViewIsPermit())
            return;

        ShareDialog dialog = new ShareDialog.Builder()
                .ArticleId(articleMeta.getId())
                .NotifyUrl(notifyUrl)
                .FromUrl(webView.getUrl())
                .build(getActivity());
        dialog.setOnSharedListener(new ShareDialog.SharedListener() {
            @Override
            public void onSuccess() {
                EventBus.getDefault().post(new ReaderShareEvent(articleId, ReaderShareEvent.State.SUCCESS));
            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onFail() {

            }

            @Override
            public void onStart() {

            }
        });
        dialog.show();
    }

    @Override
    public void onBackPressed() {
        if (webViewIsPermit() && webView.canGoBack()) {

            String[] history = getWebHistoryContext(webView);

            if (mUrlChangeListener != null)
                mUrlChangeListener.onChange(history[2],
                        history[1], history[0]);

            webView.goBack();// 返回前一个页面
        } else {
            getActivity().finish();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (webViewIsPermit()) {
            webView.onPause();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (webViewIsPermit()) {
            webView.onResume();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (webViewIsPermit()) {
            ViewGroup parent = ((ViewGroup) webView.getParent());
            if (parent != null) {
                parent.removeView(webView);
            }

            webView.removeJavascriptInterface(WebViewJavascriptBridge.JS_BRIDGE_NAME);
            webView.removeAllViews();
            webView.clearHistory();
            webView.destroy();
        }
    }

    /**
     * 获取当前WebView History的上下文状态
     * 即:当前URL,前进URL,回退URL
     *
     * @param webview
     * @return
     */
    private static String[] getWebHistoryContext(WebView webview) {
        WebBackForwardList list = webview.copyBackForwardList();

        int current = list.getCurrentIndex(),
                forward = current + 1,
                back = current - 1;

        String forward_url = forward < list.getSize() ?
                list.getItemAtIndex(forward).getOriginalUrl() : null;

        String current_url = list.getItemAtIndex(current).getOriginalUrl();
        String back_url = back >= 0 ? list.getItemAtIndex(back).getOriginalUrl() : null;

        LogUtil.d("ViewActivity", String.valueOf(current) + ":" + current_url);
        LogUtil.d("ViewActivity", String.valueOf(forward) + ":" + forward_url);
        LogUtil.d("ViewActivity", String.valueOf(back) + ":" + back_url);

        return new String[]{
                current_url, forward_url, back_url
        };
    }

    @Override
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onLoginSuccessEvent(LoginSuccessEvent event) {
        if (webViewIsPermit()) {
            loadWebPage(articleMeta);
            hasClearHistory = true;
            webView.clearHistory();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onWebRedirectEvent(WebRedirectEvent event) {
        if (event != null && event.return_url != null) {
            getActivity().finish();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onCallShareDialogEvent(CallShareDialogEvent event) {
        shareArticle();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onCollectEvent(CollectEvent event) {
        if (checkActivityExit())
            return;

        switch (event.state) {
            case DataEvent.SUCC:
                onCollectSuccess(event);
                break;
            case DataEvent.FAIL:
                ToastUtil.showCusToast(getActivity(), "收藏失败", ToastUtils.FAIL);
                break;
        }
    }

    private void onCollectSuccess(CollectEvent event) {
        ToastUtil.showCusToast(getActivity(), "收藏成功", ToastUtils.SUCCESS);
        imageCollect.setImageResource(R.drawable.nav_icon_favok);
        Article articleCollect = event.data;
        articleMeta.setArticle_collect(articleCollect.getArticle_collect());
        articleMeta.setArticle_collect_boolean(ArticleMeta.isCollect);
        updateCache(articleMeta.getId(), articleCollect.getArticle_collect());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onCollecCancleEvent(CollecCancleEvent event) {
        if (checkActivityExit())
            return;

        switch (event.state) {
            case DataEvent.SUCC:
                onCancelSuccess();

                break;
            case DataEvent.FAIL:
                ToastUtil.showCusToast(getActivity(), "取消收藏失败！", ToastUtils.FAIL);
                break;
        }
    }

    private void onCancelSuccess() {
        ToastUtil.showCusToast(getActivity(), "取消收藏", ToastUtils.SUCCESS);
        imageCollect.setImageResource(R.drawable.nav_icon_fav);
        articleMeta.setArticle_collect(null);
        articleMeta.setArticle_collect_boolean(ArticleMeta.isNotCollect);
        updateCache(articleMeta.getId(), articleMeta.getArticle_collect());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onOpenCustomHomeEvent(OpenCustomHomeEvent event) {
        Router.create(getActivity(), RouterConstants.getNativeRouter(RouterConstants.CrmIndex)).open();
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case QuesCode.QuestShareArticle:
                    shareArticle();
                    break;
                case QuesCode.QuestCollectArticle:
                    collectArticle();
                    break;
                default:
                    String path = PhotoUtils.handlePhotoResult(getActivity(), data, requestCode, resultCode);
                    if (path == null)
                        return;
                    else {
                        UploadPhotosUtil.upLoad(getActivity(), path, uploadUrl, new UploadPhotosUtil.uploadListener() {
                            @Override
                            public void onSuccess(String responseInfo) {
                                if (webViewIsPermit())
                                    webView.loadUrl("javascript:uploadImgResult(" + responseInfo + ")");
                            }

                            @Override
                            public void onFailure() {

                            }
                        });
                    }
                    break;
            }
        }
    }

    String uploadUrl = null;

    /* 检查WebView状态 */
    private boolean webViewIsPermit() {
        return webView != null && !webView.isDestory();
    }

}
